﻿/*
COPYRIGHT NOTICE

Copyright (c) 2011, S James S Stapleton
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright notice,
	  this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright notice,
	  this list of conditions and the following disclaimer in the documentation
	  and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using LocalL;
using System.Windows.Forms;

namespace LocalL.Quick
{
    /// <summary>
    /// This contains a default translator. It still needs to be set up with functions such as load, but can
    /// be quickly accessed in a static manner. I.E. it can be used with 'L.LocalizerFunctionName(...)'
    /// </summary>
    static class L
    {
        #region variables
        static public readonly int c_version_major = ALocalizer.c_version_major;
        static public readonly int c_version_minor = ALocalizer.c_version_minor;
        static public readonly int c_version_build = ALocalizer.c_version_build;
        static public readonly string c_version_string = ALocalizer.c_version_string;

        /// <summary>
        /// the default localization, so multiple don't need to be loaded.
        /// </summary>
        private static Localizer c_me = new Localizer();
        /// <summary>
        /// Get/Set the default localizer. All static localizing methods
        /// use this localizer.
        /// </summary>
        public static Localizer Me
        {
            get { return c_me; }
            set { c_me = value; }
        }
        /// <summary>
        /// Get or set the default language to localize to.
        /// </summary>
        public static string DefaultLocalization
        {
            get
            {
                return c_me.m_default_localization;
            }
            set
            {
                if(!c_me.m_localizations.ContainsKey(value))
                {
                    throw new ArgumentException("Localization '" + value + "' is not loaded, and cannot be set as the default localization.");
                }
                c_me.m_default_localization = value;
            }
        }
        /// <summary>
        /// Get/Set the stream this writes to by default.
        /// </summary>
        public static TextWriter Output
        {
            get
            {
                return c_me.m_output;
            }
            set
            {
                c_me.m_output = value;
            }
        }
        /// <summary>
        /// Get/set the string that, if at the beginning of a string sent to the translator,
        /// is removed, and indicates the string isn't L.c_me.Translated. (Default Translator)
        /// </summary>
        public static string DontTranslate
        {
            get
            {
                return c_me.m_dont_translate;
            }
            set
            {
                c_me.m_dont_translate = value;
            }
        }
        /// <summary>
        /// This controls which how different types are localized. (default localizer)
        /// </summary>
        public static Dictionary<string, TypeLocalizers> TypeLocalizers
        {
            get
            {
                return c_me.m_type_localizers;
            }
        }
        #endregion

        #region load/save functions
        /// <summary>
        /// Read the configuration from a set of file. Each file MUST have one "Localization_ID=" key, stating
        /// the identifier of the localization (such as "Localization_ID=en_US" or "Localization_ID=ru"), and one
        /// "Localization_Name=" key, stating the friendly name for the localization (such as "English, US" or
        /// "русский (Russian)").
        /// </summary>
        /// <param name="files">The files to load</param>
        /// <returns>This is the errors reported</returns>
        public static string[][] Load(params string[] files)
        {
            return L.c_me.Load(files);
        }
        /// <summary>
        /// Save the current translations (but not loaded functions/classes)
        /// </summary>
        /// <param name="file">The file to store the cinfiguration</param>
        /// <param name="localization">The localization to save</param>
        public static void Save(string file, string localization)
        {
            L.c_me.Save(file, localization);
        }
        #endregion


        #region TextWrtier implementation
        #region properties
        /// <summary>
        /// Returns the Encoding in which the output is written.
        /// </summary>
        static public Encoding Encoding
        {
            get
            {
                if(L.c_me.m_output == null) throw new NullReferenceException("NO DEFAULT OUTPUT");
                return L.c_me.m_output.Encoding;
            }
        }
        /// <summary>
        /// Gets an object that controls formatting.
        /// </summary>
        static public IFormatProvider FormatProvider
        {
            get
            {
                if(L.c_me.m_output == null) throw new NullReferenceException("NO DEFAULT OUTPUT");
                return L.c_me.m_output.FormatProvider;
            }
        }
        /// <summary>
        /// Gets or sets the line terminator string used by the current TextWriter.
        /// </summary>
        static public string NewLine
        {
            get
            {
                if(L.c_me.m_output == null) throw new NullReferenceException("NO DEFAULT OUTPUT");
                return L.c_me.m_output.NewLine;
            }
            set
            {
                if(L.c_me.m_output == null) throw new NullReferenceException("NO DEFAULT OUTPUT");
                L.c_me.m_output.NewLine = value;
            }
        }
        #endregion

        #region methods
        /// <summary>
        /// Closes the current writer and releases any system resources associated with the enclosed writer.
        /// </summary>
        static public void Close()
        {
            if(L.c_me.m_output != null) L.c_me.m_output.Close();
        }
        /// <summary>
        /// Clears all buffers for the current writer and causes any buffered data to be written to the underlying device.
        /// </summary>
        static public void Flush()
        {
            if(L.c_me.m_output != null) L.c_me.m_output.Flush();
        }
        /// <summary>
        /// Writes the text representation of a Boolean value to the text stream.
        /// </summary>
        /// <param name="value">he Boolean to write. </param>
        static public void Write(bool value)
        {
            L.c_me.m_output.Write(L.c_me.Translate(value));
        }
        /// <summary>
        /// Writes a character to the text stream.
        /// </summary>
        /// <param name="value">The character to write to the text stream. </param>
        static public void Write(char value)
        {
            L.c_me.m_output.Write(L.c_me.Translate(value));
        }
        /// <summary>
        /// Writes a character array to the text stream.
        /// </summary>
        /// <param name="buffer">The character array to write to the text stream. </param>
        static public void Write(char[] buffer)
        {
            L.c_me.m_output.Write(L.c_me.Translate(buffer));
        }
        /// <summary>
        /// Writes the text representation of a decimal value to the text stream.
        /// </summary>
        /// <param name="value">The decimal value to write. </param>
        static public void Write(decimal value)
        {
            L.c_me.m_output.Write(L.c_me.Translate(value));
        }
        /// <summary>
        /// Writes the text representation of an 8-byte floating-point value to the text stream.
        /// </summary>
        /// <param name="value">The 8-byte floating-point value to write. </param>
        static public void Write(double value)
        {
            L.c_me.m_output.Write(L.c_me.Translate(value));
        }
        /// <summary>
        /// Writes the text representation of a 4-byte signed integer to the text stream.
        /// </summary>
        /// <param name="value">The 4-byte signed integer to write. </param>
        static public void Write(int value)
        {
            L.c_me.m_output.Write(L.c_me.Translate(value));
        }
        /// <summary>
        /// Writes the text representation of an 8-byte signed integer to the text stream.
        /// </summary>
        /// <param name="value">The 8-byte signed integer to write. </param>
        static public void Write(long value)
        {
            L.c_me.m_output.Write(L.c_me.Translate(value));
        }
        /// <summary>
        /// Writes the text representation of an object to the text stream by calling ToString on that object.
        /// </summary>
        /// <param name="value">The object to write. </param>
        static public void Write(Object value)
        {
            L.c_me.m_output.Write(L.c_me.Translate(value));
        }
        /// <summary>
        /// Writes the text representation of a 4-byte floating-point value to the text stream.
        /// </summary>
        /// <param name="value">The 4-byte floating-point value to write. </param>
        static public void Write(float value)
        {
            L.c_me.m_output.Write(L.c_me.Translate(value));
        }
        /// <summary>
        /// Writes a string to the text stream.
        /// </summary>
        /// <param name="value">The string to write. </param>
        static public void Write(string value)
        {
            L.c_me.m_output.Write(L.c_me.Translate(value));
        }
        /// <summary>
        /// Writes the text representation of a 4-byte unsigned integer to the text stream.
        /// </summary>
        /// <param name="value">The 4-byte unsigned integer to write. </param>
        static public void Write(uint value)
        {
            L.c_me.m_output.Write(L.c_me.Translate(value));
        }
        /// <summary>
        /// Writes the text representation of an 8-byte unsigned integer to the text stream.
        /// </summary>
        /// <param name="value">The 8-byte unsigned integer to write. </param>
        static public void Write(ulong value)
        {
            L.c_me.m_output.Write(L.c_me.Translate(value));
        }
        /// <summary>
        /// Writes out a formatted string, using the same semantics as String.Format.
        /// </summary>
        /// <param name="format">The formatting string.</param>
        /// <param name="arg0">An object to write into the formatted string. (This is converted to a string)</param>
        static public void Write(string format, Object arg0)
        {
            L.c_me.m_output.Write(format, L.c_me.Translate(arg0));
        }
        /// <summary>
        /// Writes out a formatted string, using the same semantics as String.Format.
        /// </summary>
        /// <param name="format">The formatting string.</param>
        /// <param name="arg">The object array to write into the formatted string. (This is converted to a string)</param>
        static public void Write(string format, params Object[] arg)
        {
            if(L.c_me.m_default_localization == null)
            {
                //we don't localize this - there is no default
                throw new NullReferenceException("Cannot localize, no default localization set.");
            }
            object[] write = new object[arg.Length];
            for(int i = 0; i < arg.Length; i++) write[i] = L.c_me.Translate_(arg[i]);
            L.c_me.m_output.Write(format, write);
        }
        /// <summary>
        /// Writes a subarray of characters to the text stream.
        /// </summary>
        /// <param name="buffer">The character array to write data from. </param>
        /// <param name="index">Starting index in the buffer. </param>
        /// <param name="count">The number of characters to write. </param>
        static public void Write(char[] buffer, int index, int count)
        {
            char[] o = new char[count];
            for(int i = 0; i < count; i++) o[i] = buffer[index + i];
            L.c_me.m_output.Write(L.c_me.Translate(o));
        }
        /// <summary>
        /// Writes out a formatted string, using the same semantics as String.Format.
        /// </summary>
        /// <param name="format">The formatting string. </param>
        /// <param name="arg0">An object to write into the formatted string. </param>
        /// <param name="arg1">An object to write into the formatted string. </param>
        static public void Write(string format, Object arg0, Object arg1)
        {
            if(L.c_me.m_default_localization == null)
            {
                //we don't localize this - there is no default
                throw new NullReferenceException("Cannot localize, no default localization set.");
            }
            L.c_me.m_output.Write(format, L.c_me.Translate_(arg0), L.c_me.Translate_(arg1));
        }
        /// <summary>
        /// Writes out a formatted string, using the same semantics as String.Format.
        /// </summary>
        /// <param name="format">The formatting string. </param>
        /// <param name="arg0">An object to write into the formatted string. </param>
        /// <param name="arg1">An object to write into the formatted string. </param>
        /// <param name="arg2">An object to write into the formatted string. </param>
        static public void Write(string format, Object arg0, Object arg1, Object arg2)
        {
            if(L.c_me.m_default_localization == null)
            {
                //we don't localize this - there is no default
                throw new NullReferenceException("Cannot localize, no default localization set.");
            }
            L.c_me.m_output.Write(format, L.c_me.Translate_(arg0), L.c_me.Translate_(arg1), L.c_me.Translate_(arg2));
        }
        /// <summary>
        /// Not actually part o fthe TextWriter class, but important for us!
        /// </summary>
        /// <param name="output">The objects to write, each one that is not a NotLocalizable is output.</param>
        static public void Write(params object[] output)
        {
            if(L.c_me.m_default_localization == null)
            {
                //we don't localize this - there is no default
                throw new NullReferenceException("Cannot localize, no default localization set.");
            }

            foreach(object s in output)
            {
                if(s.GetType() == typeof(string))
                    L.c_me.m_output.Write((string)L.c_me.Translate_(s));
                else
                    L.c_me.m_output.Write(L.c_me.Translate_(s));
            }
        }
        /// <summary>
        /// Writes the text representation of a Boolean value to the text stream.
        /// </summary>
        /// <param name="value">he Boolean to write. </param>
        static public void WriteLine(bool value)
        {
            L.c_me.m_output.WriteLine(L.c_me.Translate(value));
        }
        /// <summary>
        /// Writes a character to the text stream.
        /// </summary>
        /// <param name="value">The character to write to the text stream. </param>
        static public void WriteLine(char value)
        {
            L.c_me.m_output.WriteLine(L.c_me.Translate(value));
        }
        /// <summary>
        /// Writes a character array to the text stream.
        /// </summary>
        /// <param name="buffer">The character array to write to the text stream. </param>
        static public void WriteLine(char[] buffer)
        {
            L.c_me.m_output.WriteLine(L.c_me.Translate(buffer));
        }
        /// <summary>
        /// Writes the text representation of a decimal value to the text stream.
        /// </summary>
        /// <param name="value">The decimal value to write. </param>
        static public void WriteLine(decimal value)
        {
            L.c_me.m_output.WriteLine(L.c_me.Translate(value));
        }
        /// <summary>
        /// Writes the text representation of an 8-byte floating-point value to the text stream.
        /// </summary>
        /// <param name="value">The 8-byte floating-point value to write. </param>
        static public void WriteLine(double value)
        {
            L.c_me.m_output.WriteLine(L.c_me.Translate(value));
        }
        /// <summary>
        /// Writes the text representation of a 4-byte signed integer to the text stream.
        /// </summary>
        /// <param name="value">The 4-byte signed integer to write. </param>
        static public void WriteLine(int value)
        {
            L.c_me.m_output.WriteLine(L.c_me.Translate(value));
        }
        /// <summary>
        /// Writes the text representation of an 8-byte signed integer to the text stream.
        /// </summary>
        /// <param name="value">The 8-byte signed integer to write. </param>
        static public void WriteLine(long value)
        {
            L.c_me.m_output.WriteLine(L.c_me.Translate(value));
        }
        /// <summary>
        /// Writes the text representation of an object to the text stream by calling ToString on that object.
        /// </summary>
        /// <param name="value">The object to write. </param>
        static public void WriteLine(Object value)
        {
            L.c_me.m_output.WriteLine(L.c_me.Translate(value));
        }
        /// <summary>
        /// Writes the text representation of a 4-byte floating-point value to the text stream.
        /// </summary>
        /// <param name="value">The 4-byte floating-point value to write. </param>
        static public void WriteLine(float value)
        {
            L.c_me.m_output.WriteLine(L.c_me.Translate(value));
        }
        /// <summary>
        /// Writes a string to the text stream.
        /// </summary>
        /// <param name="value">The string to write. </param>
        static public void WriteLine(string value)
        {
            L.c_me.m_output.WriteLine(L.c_me.Translate(value));
        }
        /// <summary>
        /// Writes the text representation of a 4-byte unsigned integer to the text stream.
        /// </summary>
        /// <param name="value">The 4-byte unsigned integer to write. </param>
        static public void WriteLine(uint value)
        {
            L.c_me.m_output.WriteLine(L.c_me.Translate(value));
        }
        /// <summary>
        /// Writes the text representation of an 8-byte unsigned integer to the text stream.
        /// </summary>
        /// <param name="value">The 8-byte unsigned integer to write. </param>
        static public void WriteLine(ulong value)
        {
            L.c_me.m_output.WriteLine(L.c_me.Translate(value));
        }
        /// <summary>
        /// Writes out a formatted string, using the same semantics as String.Format.
        /// </summary>
        /// <param name="format">The formatting string.</param>
        /// <param name="arg0">An object to write into the formatted string. (This is converted to a string)</param>
        static public void WriteLine(string format, Object arg0)
        {
            L.c_me.m_output.WriteLine(format, L.c_me.Translate(arg0));
        }
        /// <summary>
        /// Writes out a formatted string, using the same semantics as String.Format.
        /// </summary>
        /// <param name="format">The formatting string.</param>
        /// <param name="arg">The object array to write into the formatted string. (This is converted to a string)</param>
        static public void WriteLine(string format, params Object[] arg)
        {
            if(L.c_me.m_default_localization == null)
            {
                //we don't localize this - there is no default
                throw new NullReferenceException("Cannot localize, no default localization set.");
            }
            object[] write = new object[arg.Length];
            for(int i = 0; i < arg.Length; i++) write[i] = L.c_me.Translate_(arg[i]);
            L.c_me.m_output.WriteLine(format, write);
        }
        /// <summary>
        /// Writes a subarray of characters to the text stream.
        /// </summary>
        /// <param name="buffer">The character array to write data from. </param>
        /// <param name="index">Starting index in the buffer. </param>
        /// <param name="count">The number of characters to write. </param>
        static public void WriteLine(char[] buffer, int index, int count)
        {
            char[] o = new char[count];
            for(int i = 0; i < count; i++) o[i] = buffer[index + i];
            L.c_me.m_output.WriteLine(L.c_me.Translate(o));
        }
        /// <summary>
        /// Writes out a formatted string, using the same semantics as String.Format.
        /// </summary>
        /// <param name="format">The formatting string. </param>
        /// <param name="arg0">An object to write into the formatted string. </param>
        /// <param name="arg1">An object to write into the formatted string. </param>
        static public void WriteLine(string format, Object arg0, Object arg1)
        {
            if(L.c_me.m_default_localization == null)
            {
                //we don't localize this - there is no default
                throw new NullReferenceException("Cannot localize, no default localization set.");
            }
            L.c_me.m_output.WriteLine(format, L.c_me.Translate_(arg0), L.c_me.Translate_(arg1));
        }
        /// <summary>
        /// Writes out a formatted string, using the same semantics as String.Format.
        /// </summary>
        /// <param name="format">The formatting string. </param>
        /// <param name="arg0">An object to write into the formatted string. </param>
        /// <param name="arg1">An object to write into the formatted string. </param>
        /// <param name="arg2">An object to write into the formatted string. </param>
        static public void WriteLine(string format, Object arg0, Object arg1, Object arg2)
        {
            if(L.c_me.m_default_localization == null)
            {
                //we don't localize this - there is no default
                throw new NullReferenceException("Cannot localize, no default localization set.");
            }
            L.c_me.m_output.WriteLine(format, L.c_me.Translate_(arg0), L.c_me.Translate_(arg1), L.c_me.Translate_(arg2));
        }
        /// <summary>
        /// Not actually part o fthe TextWriter class, but important for us!
        /// </summary>
        /// <param name="output">The strings to write, each one that is not a NotLocalizable is output.</param>
        static public void WriteLine(params object[] output)
        {
            if(L.c_me.m_default_localization == null)
            {
                //we don't localize this - there is no default
                throw new NullReferenceException("Cannot localize, no default localization set.");
            }

            foreach(object s in output)
            {
                if(s.GetType() == typeof(string))
                    L.c_me.m_output.Write((string)L.c_me.Translate_(s));
                else
                    L.c_me.m_output.Write(L.c_me.Translate_(s));
            }
            L.c_me.m_output.WriteLine();
        }
        #endregion
        #endregion

        #region Abitrary-Target-TextWrtier implementation
        /// <summary>
        /// Writes the text representation of a Boolean value to the text stream.
        /// </summary>
        /// <param name="w">The text writer to send output to.</param>
        /// <param name="value">he Boolean to write. </param>
        static public void Write(TextWriter w, bool value)
        {
            w.Write((L.c_me.Translate(value)));
        }
        /// <summary>
        /// Writes a character to the text stream.
        /// </summary>
        /// <param name="w">The text writer to send output to.</param>
        /// <param name="value">The character to write to the text stream. </param>
        static public void Write(TextWriter w, char value)
        {
            w.Write((L.c_me.Translate(value)));
        }
        /// <summary>
        /// Writes a character array to the text stream.
        /// </summary>
        /// <param name="w">The text writer to send output to.</param>
        /// <param name="buffer">The character array to write to the text stream. </param>
        static public void Write(TextWriter w, char[] buffer)
        {
            w.Write((L.c_me.Translate(buffer)));
        }
        /// <summary>
        /// Writes the text representation of a decimal value to the text stream.
        /// </summary>
        /// <param name="w">The text writer to send output to.</param>
        /// <param name="value">The decimal value to write. </param>
        static public void Write(TextWriter w, decimal value)
        {
            w.Write((L.c_me.Translate(value)));
        }
        /// <summary>
        /// Writes the text representation of an 8-byte floating-point value to the text stream.
        /// </summary>
        /// <param name="w">The text writer to send output to.</param>
        /// <param name="value">The 8-byte floating-point value to write. </param>
        static public void Write(TextWriter w, double value)
        {
            w.Write((L.c_me.Translate(value)));
        }
        /// <summary>
        /// Writes the text representation of a 4-byte signed integer to the text stream.
        /// </summary>
        /// <param name="w">The text writer to send output to.</param>
        /// <param name="value">The 4-byte signed integer to write. </param>
        static public void Write(TextWriter w, int value)
        {
            w.Write((L.c_me.Translate(value)));
        }
        /// <summary>
        /// Writes the text representation of an 8-byte signed integer to the text stream.
        /// </summary>
        /// <param name="w">The text writer to send output to.</param>
        /// <param name="value">The 8-byte signed integer to write. </param>
        static public void Write(TextWriter w, long value)
        {
            w.Write((L.c_me.Translate(value)));
        }
        /// <summary>
        /// Writes the text representation of an object to the text stream by calling ToString on that object.
        /// </summary>
        /// <param name="w">The text writer to send output to.</param>
        /// <param name="value">The object to write. </param>
        static public void Write(TextWriter w, Object value)
        {
            w.Write((L.c_me.Translate(value)));
        }
        /// <summary>
        /// Writes the text representation of a 4-byte floating-point value to the text stream.
        /// </summary>
        /// <param name="w">The text writer to send output to.</param>
        /// <param name="value">The 4-byte floating-point value to write. </param>
        static public void Write(TextWriter w, float value)
        {
            w.Write((L.c_me.Translate(value)));
        }
        /// <summary>
        /// Writes a string to the text stream.
        /// </summary>
        /// <param name="w">The text writer to send output to.</param>
        /// <param name="value">The string to write. </param>
        static public void Write(TextWriter w, string value)
        {
            w.Write((L.c_me.Translate(value)));
        }
        /// <summary>
        /// Writes the text representation of a 4-byte unsigned integer to the text stream.
        /// </summary>
        /// <param name="w">The text writer to send output to.</param>
        /// <param name="value">The 4-byte unsigned integer to write. </param>
        static public void Write(TextWriter w, uint value)
        {
            w.Write((L.c_me.Translate(value)));
        }
        /// <summary>
        /// Writes the text representation of an 8-byte unsigned integer to the text stream.
        /// </summary>
        /// <param name="w">The text writer to send output to.</param>
        /// <param name="value">The 8-byte unsigned integer to write. </param>
        static public void Write(TextWriter w, ulong value)
        {
            w.Write((L.c_me.Translate(value)));
        }
        /// <summary>
        /// Writes out a formatted string, using the same semantics as String.Format.
        /// </summary>
        /// <param name="w">The text writer to send output to.</param>
        /// <param name="format">The formatting string.</param>
        /// <param name="arg0">An object to write into the formatted string. (This is converted to a string)</param>
        static public void Write(TextWriter w, string format, Object arg0)
        {
            w.Write(format, L.c_me.Translate(arg0));
        }
        /// <summary>
        /// Writes out a formatted string, using the same semantics as String.Format.
        /// </summary>
        /// <param name="w">The text writer to send output to.</param>
        /// <param name="format">The formatting string.</param>
        /// <param name="arg">The object array to write into the formatted string. (This is converted to a string)</param>
        static public void Write(TextWriter w, string format, params Object[] arg)
        {
            if(L.c_me.m_default_localization == null)
            {
                //we don't localize this - there is no default
                throw new NullReferenceException("Cannot localize, no default localization set.");
            }
            object[] write = new object[arg.Length];
            for(int i = 0; i < arg.Length; i++) write[i] = L.c_me.Translate_(arg[i]);
            w.Write(format, write);
        }
        /// <summary>
        /// Writes a subarray of characters to the text stream.
        /// </summary>
        /// <param name="w">The text writer to send output to.</param>
        /// <param name="buffer">The character array to write data from. </param>
        /// <param name="index">Starting index in the buffer. </param>
        /// <param name="count">The number of characters to write. </param>
        static public void Write(TextWriter w, char[] buffer, int index, int count)
        {
            char[] o = new char[count];
            for(int i = 0; i < count; i++) o[i] = buffer[index + i];
            w.Write(L.c_me.Translate(o));
        }
        /// <summary>
        /// Writes out a formatted string, using the same semantics as String.Format.
        /// </summary>
        /// <param name="w">The text writer to send output to.</param>
        /// <param name="format">The formatting string. </param>
        /// <param name="arg0">An object to write into the formatted string. </param>
        /// <param name="arg1">An object to write into the formatted string. </param>
        static public void Write(TextWriter w, string format, Object arg0, Object arg1)
        {
            if(L.c_me.m_default_localization == null)
            {
                //we don't localize this - there is no default
                throw new NullReferenceException("Cannot localize, no default localization set.");
            }
            w.Write(format, L.c_me.Translate_(arg0), L.c_me.Translate_(arg1));
        }
        /// <summary>
        /// Writes out a formatted string, using the same semantics as String.Format.
        /// </summary>
        /// <param name="w">The text writer to send output to.</param>
        /// <param name="format">The formatting string. </param>
        /// <param name="arg0">An object to write into the formatted string. </param>
        /// <param name="arg1">An object to write into the formatted string. </param>
        /// <param name="arg2">An object to write into the formatted string. </param>
        static public void Write(TextWriter w, string format, Object arg0, Object arg1, Object arg2)
        {
            if(L.c_me.m_default_localization == null)
            {
                //we don't localize this - there is no default
                throw new NullReferenceException("Cannot localize, no default localization set.");
            }
            w.Write(format, L.c_me.Translate_(arg0), L.c_me.Translate_(arg1), L.c_me.Translate_(arg2));
        }
        /// <summary>
        /// Not actually part o fthe TextWriter class, but important for us!
        /// </summary>
        /// <param name="w">The text writer to send output to.</param>
        /// <param name="output">The objects to write, each one that is not a NotLocalizable is output.</param>
        static public void Write(TextWriter w, params object[] output)
        {
            if(L.c_me.m_default_localization == null)
            {
                //we don't localize this - there is no default
                throw new NullReferenceException("Cannot localize, no default localization set.");
            }

            foreach(object s in output)
            {
                if(s.GetType() == typeof(string))
                    w.Write((string)L.c_me.Translate_(s));
                else
                    w.Write(L.c_me.Translate_(s));
            }
        }
        /// <summary>
        /// Writes the text representation of a Boolean value to the text stream.
        /// </summary>
        /// <param name="w">The text writer to send output to.</param>
        /// <param name="value">he Boolean to write. </param>
        static public void WriteLine(TextWriter w, bool value)
        {
            w.WriteLine(L.c_me.Translate(value));
        }
        /// <summary>
        /// Writes a character to the text stream.
        /// </summary>
        /// <param name="w">The text writer to send output to.</param>
        /// <param name="value">The character to write to the text stream. </param>
        static public void WriteLine(TextWriter w, char value)
        {
            w.WriteLine(L.c_me.Translate(value));
        }
        /// <summary>
        /// Writes a character array to the text stream.
        /// </summary>
        /// <param name="w">The text writer to send output to.</param>
        /// <param name="buffer">The character array to write to the text stream. </param>
        static public void WriteLine(TextWriter w, char[] buffer)
        {
            w.WriteLine(L.c_me.Translate(buffer));
        }
        /// <summary>
        /// Writes the text representation of a decimal value to the text stream.
        /// </summary>
        /// <param name="w">The text writer to send output to.</param>
        /// <param name="value">The decimal value to write. </param>
        static public void WriteLine(TextWriter w, decimal value)
        {
            w.WriteLine(L.c_me.Translate(value));
        }
        /// <summary>
        /// Writes the text representation of an 8-byte floating-point value to the text stream.
        /// </summary>
        /// <param name="w">The text writer to send output to.</param>
        /// <param name="value">The 8-byte floating-point value to write. </param>
        static public void WriteLine(TextWriter w, double value)
        {
            w.WriteLine(L.c_me.Translate(value));
        }
        /// <summary>
        /// Writes the text representation of a 4-byte signed integer to the text stream.
        /// </summary>
        /// <param name="w">The text writer to send output to.</param>
        /// <param name="value">The 4-byte signed integer to write. </param>
        static public void WriteLine(TextWriter w, int value)
        {
            w.WriteLine(L.c_me.Translate(value));
        }
        /// <summary>
        /// Writes the text representation of an 8-byte signed integer to the text stream.
        /// </summary>
        /// <param name="w">The text writer to send output to.</param>
        /// <param name="value">The 8-byte signed integer to write. </param>
        static public void WriteLine(TextWriter w, long value)
        {
            w.WriteLine(L.c_me.Translate(value));
        }
        /// <summary>
        /// Writes the text representation of an object to the text stream by calling ToString on that object.
        /// </summary>
        /// <param name="w">The text writer to send output to.</param>
        /// <param name="value">The object to write. </param>
        static public void WriteLine(TextWriter w, Object value)
        {
            w.WriteLine(L.c_me.Translate(value));
        }
        /// <summary>
        /// Writes the text representation of a 4-byte floating-point value to the text stream.
        /// </summary>
        /// <param name="w">The text writer to send output to.</param>
        /// <param name="value">The 4-byte floating-point value to write. </param>
        static public void WriteLine(TextWriter w, float value)
        {
            w.WriteLine(L.c_me.Translate(value));
        }
        /// <summary>
        /// Writes a string to the text stream.
        /// </summary>
        /// <param name="w">The text writer to send output to.</param>
        /// <param name="value">The string to write. </param>
        static public void WriteLine(TextWriter w, string value)
        {
            w.WriteLine(L.c_me.Translate(value));
        }
        /// <summary>
        /// Writes the text representation of a 4-byte unsigned integer to the text stream.
        /// </summary>
        /// <param name="w">The text writer to send output to.</param>
        /// <param name="value">The 4-byte unsigned integer to write. </param>
        static public void WriteLine(TextWriter w, uint value)
        {
            w.WriteLine(L.c_me.Translate(value));
        }
        /// <summary>
        /// Writes the text representation of an 8-byte unsigned integer to the text stream.
        /// </summary>
        /// <param name="w">The text writer to send output to.</param>
        /// <param name="value">The 8-byte unsigned integer to write. </param>
        static public void WriteLine(TextWriter w, ulong value)
        {
            w.WriteLine(L.c_me.Translate(value));
        }
        /// <summary>
        /// Writes out a formatted string, using the same semantics as String.Format.
        /// </summary>
        /// <param name="w">The text writer to send output to.</param>
        /// <param name="format">The formatting string.</param>
        /// <param name="arg0">An object to write into the formatted string. (This is converted to a string)</param>
        static public void WriteLine(TextWriter w, string format, Object arg0)
        {
            w.WriteLine(format, L.c_me.Translate(arg0));
        }
        /// <summary>
        /// Writes out a formatted string, using the same semantics as String.Format.
        /// </summary>
        /// <param name="w">The text writer to send output to.</param>
        /// <param name="format">The formatting string.</param>
        /// <param name="arg">The object array to write into the formatted string. (This is converted to a string)</param>
        static public void WriteLine(TextWriter w, string format, params Object[] arg)
        {
            if(L.c_me.m_default_localization == null)
            {
                //we don't localize this - there is no default
                throw new NullReferenceException("Cannot localize, no default localization set.");
            }
            object[] write = new object[arg.Length];
            for(int i = 0; i < arg.Length; i++) write[i] = L.c_me.Translate_(arg[i]);
            w.WriteLine(format, write);
        }
        /// <summary>
        /// Writes a subarray of characters to the text stream.
        /// </summary>
        /// <param name="w">The text writer to send output to.</param>
        /// <param name="buffer">The character array to write data from. </param>
        /// <param name="index">Starting index in the buffer. </param>
        /// <param name="count">The number of characters to write. </param>
        static public void WriteLine(TextWriter w, char[] buffer, int index, int count)
        {
            char[] o = new char[count];
            for(int i = 0; i < count; i++) o[i] = buffer[index + i];
            w.WriteLine(L.c_me.Translate(o));
        }
        /// <summary>
        /// Writes out a formatted string, using the same semantics as String.Format.
        /// </summary>
        /// <param name="w">The text writer to send output to.</param>
        /// <param name="format">The formatting string. </param>
        /// <param name="arg0">An object to write into the formatted string. </param>
        /// <param name="arg1">An object to write into the formatted string. </param>
        static public void WriteLine(TextWriter w, string format, Object arg0, Object arg1)
        {
            if(L.c_me.m_default_localization == null)
            {
                //we don't localize this - there is no default
                throw new NullReferenceException("Cannot localize, no default localization set.");
            }
            w.WriteLine(format, L.c_me.Translate_(arg0), L.c_me.Translate_(arg1));
        }
        /// <summary>
        /// Writes out a formatted string, using the same semantics as String.Format.
        /// </summary>
        /// <param name="w">The text writer to send output to.</param>
        /// <param name="format">The formatting string. </param>
        /// <param name="arg0">An object to write into the formatted string. </param>
        /// <param name="arg1">An object to write into the formatted string. </param>
        /// <param name="arg2">An object to write into the formatted string. </param>
        static public void WriteLine(TextWriter w, string format, Object arg0, Object arg1, Object arg2)
        {
            if(L.c_me.m_default_localization == null)
            {
                //we don't localize this - there is no default
                throw new NullReferenceException("Cannot localize, no default localization set.");
            }
            w.WriteLine(format, L.c_me.Translate_(arg0), L.c_me.Translate_(arg1), L.c_me.Translate_(arg2));
        }
        /// <summary>
        /// Not actually part o fthe TextWriter class, but important for us!
        /// </summary>
        /// <param name="w">The text writer to send output to.</param>
        /// <param name="output">The strings to write, each one that is not a NotLocalizable is output.</param>
        static public void WriteLine(TextWriter w, params object[] output)
        {
            if(L.c_me.m_default_localization == null)
            {
                //we don't localize this - there is no default
                throw new NullReferenceException("Cannot localize, no default localization set.");
            }

            foreach(object s in output)
            {
                if(s.GetType() == typeof(string))
                    w.Write((string)L.c_me.Translate_(s));
                else
                    w.Write(L.c_me.Translate_(s));
            }
            w.WriteLine();
        }
        #endregion

        #region WinForms TextWriter-like implementation
        /// <summary>
        /// Writes the text representation of a Boolean value to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="value">he Boolean to write. </param>
        static public void Write(Control c, bool value)
        {
            c.Text += L.c_me.Translate(value);
        }
        /// <summary>
        /// Writes a character to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="value">The character to write to the text stream. </param>
        static public void Write(Control c, char value)
        {
            c.Text += L.c_me.Translate(value);
        }
        /// <summary>
        /// Writes a character array to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="buffer">The character array to write to the text stream. </param>
        static public void Write(Control c, char[] buffer)
        {
            c.Text += L.c_me.Translate(buffer);
        }
        /// <summary>
        /// Writes the text representation of a decimal value to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="value">The decimal value to write. </param>
        static public void Write(Control c, decimal value)
        {
            c.Text += L.c_me.Translate(value);
        }
        /// <summary>
        /// Writes the text representation of an 8-byte floating-point value to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="value">The 8-byte floating-point value to write. </param>
        static public void Write(Control c, double value)
        {
            c.Text += L.c_me.Translate(value);
        }
        /// <summary>
        /// Writes the text representation of a 4-byte signed integer to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="value">The 4-byte signed integer to write. </param>
        static public void Write(Control c, int value)
        {
            c.Text += L.c_me.Translate(value);
        }
        /// <summary>
        /// Writes the text representation of an 8-byte signed integer to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="value">The 8-byte signed integer to write. </param>
        static public void Write(Control c, long value)
        {
            c.Text += L.c_me.Translate(value);
        }
        /// <summary>
        /// Writes the text representation of an object to the text stream by calling ToString on that object.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="value">The object to write. </param>
        static public void Write(Control c, Object value)
        {
            c.Text += L.c_me.Translate(value);
        }
        /// <summary>
        /// Writes the text representation of a 4-byte floating-point value to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="value">The 4-byte floating-point value to write. </param>
        static public void Write(Control c, float value)
        {
            c.Text += L.c_me.Translate(value);
        }
        /// <summary>
        /// Writes a string to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="value">The string to write. </param>
        static public void Write(Control c, string value)
        {
            c.Text += L.c_me.Translate(value);
        }
        /// <summary>
        /// Writes the text representation of a 4-byte unsigned integer to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="value">The 4-byte unsigned integer to write. </param>
        static public void Write(Control c, uint value)
        {
            c.Text += L.c_me.Translate(value);
        }
        /// <summary>
        /// Writes the text representation of an 8-byte unsigned integer to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="value">The 8-byte unsigned integer to write. </param>
        static public void Write(Control c, ulong value)
        {
            c.Text += L.c_me.Translate(value);
        }
        /// <summary>
        /// Writes out a formatted string, using the same semantics as String.Format.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="format">The formatting string.</param>
        /// <param name="arg0">An object to write into the formatted string. (This is converted to a string)</param>
        static public void Write(Control c, string format, Object arg0)
        {
            c.Text += String.Format(format, L.c_me.Translate(arg0));
        }
        /// <summary>
        /// Writes out a formatted string, using the same semantics as String.Format.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="format">The formatting string.</param>
        /// <param name="arg">The object array to write into the formatted string. (This is converted to a string)</param>
        static public void Write(Control c, string format, params Object[] arg)
        {
            if(L.c_me.m_default_localization == null)
            {
                //we don't localize this - there is no default
                throw new NullReferenceException("Cannot localize, no default localization set.");
            }
            object[] write = new object[arg.Length];
            for(int i = 0; i < arg.Length; i++) write[i] = L.c_me.Translate_(arg[i]);
            c.Text += String.Format(format, write);
        }
        /// <summary>
        /// Writes a subarray of characters to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="buffer">The character array to write data from. </param>
        /// <param name="index">Starting index in the buffer. </param>
        /// <param name="count">The number of characters to write. </param>
        static public void Write(Control c, char[] buffer, int index, int count)
        {
            char[] o = new char[count];
            for(int i = 0; i < count; i++) o[i] = buffer[index + i];
            c.Text += String.Format(L.c_me.Translate(o));
        }
        /// <summary>
        /// Writes out a formatted string, using the same semantics as String.Format.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="format">The formatting string. </param>
        /// <param name="arg0">An object to write into the formatted string. </param>
        /// <param name="arg1">An object to write into the formatted string. </param>
        static public void Write(Control c, string format, Object arg0, Object arg1)
        {
            if(L.c_me.m_default_localization == null)
            {
                //we don't localize this - there is no default
                throw new NullReferenceException("Cannot localize, no default localization set.");
            }
            c.Text += String.Format(format, L.c_me.Translate_(arg0), L.c_me.Translate_(arg1));
        }
        /// <summary>
        /// Writes out a formatted string, using the same semantics as String.Format.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="format">The formatting string. </param>
        /// <param name="arg0">An object to write into the formatted string. </param>
        /// <param name="arg1">An object to write into the formatted string. </param>
        /// <param name="arg2">An object to write into the formatted string. </param>
        static public void Write(Control c, string format, Object arg0, Object arg1, Object arg2)
        {
            if(L.c_me.m_default_localization == null)
            {
                //we don't localize this - there is no default
                throw new NullReferenceException("Cannot localize, no default localization set.");
            }
            c.Text += String.Format(format, L.c_me.Translate_(arg0), L.c_me.Translate_(arg1), L.c_me.Translate_(arg2));
        }
        /// <summary>
        /// Not actually part o fthe TextWriter class, but important for us!
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="output">The objects to write, each one that is not a NotLocalizable is output.</param>
        static public void Write(Control c, params object[] output)
        {
            if(L.c_me.m_default_localization == null)
            {
                //we don't localize this - there is no default
                throw new NullReferenceException("Cannot localize, no default localization set.");
            }
            if(c.Text == null) c.Text = "";
            foreach(object s in output)
            {
                if(s.GetType() == typeof(string))
                    c.Text += L.c_me.Translate_(s);
                else
                    c.Text += L.c_me.Translate_(s);
            }
        }

        /// <summary>
        /// Writes the text representation of a Boolean value to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="value">he Boolean to write. </param>
        static public void WriteLine(Control c, bool value)
        {
            c.Text += L.c_me.Translate(value) + "\n";
        }
        /// <summary>
        /// Writes a character to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="value">The character to write to the text stream. </param>
        static public void WriteLine(Control c, char value)
        {
            c.Text += L.c_me.Translate(value) + "\n";
        }
        /// <summary>
        /// Writes a character array to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="buffer">The character array to write to the text stream. </param>
        static public void WriteLine(Control c, char[] buffer)
        {
            c.Text += L.c_me.Translate(buffer) + "\n";
        }
        /// <summary>
        /// Writes the text representation of a decimal value to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="value">The decimal value to write. </param>
        static public void WriteLine(Control c, decimal value)
        {
            c.Text += L.c_me.Translate(value) + "\n";
        }
        /// <summary>
        /// Writes the text representation of an 8-byte floating-point value to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="value">The 8-byte floating-point value to write. </param>
        static public void WriteLine(Control c, double value)
        {
            c.Text += L.c_me.Translate(value) + "\n";
        }
        /// <summary>
        /// Writes the text representation of a 4-byte signed integer to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="value">The 4-byte signed integer to write. </param>
        static public void WriteLine(Control c, int value)
        {
            c.Text += L.c_me.Translate(value) + "\n";
        }
        /// <summary>
        /// Writes the text representation of an 8-byte signed integer to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="value">The 8-byte signed integer to write. </param>
        static public void WriteLine(Control c, long value)
        {
            c.Text += L.c_me.Translate(value) + "\n";
        }
        /// <summary>
        /// Writes the text representation of an object to the text stream by calling ToString on that object.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="value">The object to write. </param>
        static public void WriteLine(Control c, Object value)
        {
            c.Text += L.c_me.Translate(value) + "\n";
        }
        /// <summary>
        /// Writes the text representation of a 4-byte floating-point value to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="value">The 4-byte floating-point value to write. </param>
        static public void WriteLine(Control c, float value)
        {
            c.Text += L.c_me.Translate(value) + "\n";
        }
        /// <summary>
        /// Writes a string to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="value">The string to write. </param>
        static public void WriteLine(Control c, string value)
        {
            c.Text += L.c_me.Translate(value) + "\n";
        }
        /// <summary>
        /// Writes the text representation of a 4-byte unsigned integer to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="value">The 4-byte unsigned integer to write. </param>
        static public void WriteLine(Control c, uint value)
        {
            c.Text += L.c_me.Translate(value) + "\n";
        }
        /// <summary>
        /// Writes the text representation of an 8-byte unsigned integer to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="value">The 8-byte unsigned integer to write. </param>
        static public void WriteLine(Control c, ulong value)
        {
            c.Text += L.c_me.Translate(value) + "\n";
        }
        /// <summary>
        /// Writes out a formatted string, using the same semantics as String.Format.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="format">The formatting string.</param>
        /// <param name="arg0">An object to write into the formatted string. (This is converted to a string)</param>
        static public void WriteLine(Control c, string format, Object arg0)
        {
            c.Text += String.Format(format, L.c_me.Translate(arg0)) + "\n";
        }
        /// <summary>
        /// Writes out a formatted string, using the same semantics as String.Format.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="format">The formatting string.</param>
        /// <param name="arg">The object array to write into the formatted string. (This is converted to a string)</param>
        static public void WriteLine(Control c, string format, params Object[] arg)
        {
            if(L.c_me.m_default_localization == null)
            {
                //we don't localize this - there is no default
                throw new NullReferenceException("Cannot localize, no default localization set.");
            }
            object[] write = new object[arg.Length];
            for(int i = 0; i < arg.Length; i++) write[i] = L.c_me.Translate_(arg[i]);
            c.Text += String.Format(format, write) + "\n";
        }
        /// <summary>
        /// Writes a subarray of characters to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="buffer">The character array to write data from. </param>
        /// <param name="index">Starting index in the buffer. </param>
        /// <param name="count">The number of characters to write. </param>
        static public void WriteLine(Control c, char[] buffer, int index, int count)
        {
            char[] o = new char[count];
            for(int i = 0; i < count; i++) o[i] = buffer[index + i];
            c.Text += String.Format(L.c_me.Translate(o)) + "\n";
        }
        /// <summary>
        /// Writes out a formatted string, using the same semantics as String.Format.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="format">The formatting string. </param>
        /// <param name="arg0">An object to write into the formatted string. </param>
        /// <param name="arg1">An object to write into the formatted string. </param>
        static public void WriteLine(Control c, string format, Object arg0, Object arg1)
        {
            if(L.c_me.m_default_localization == null)
            {
                //we don't localize this - there is no default
                throw new NullReferenceException("Cannot localize, no default localization set.");
            }
            c.Text += String.Format(format, L.c_me.Translate_(arg0), L.c_me.Translate_(arg1)) + "\n";
        }
        /// <summary>
        /// Writes out a formatted string, using the same semantics as String.Format.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="format">The formatting string. </param>
        /// <param name="arg0">An object to write into the formatted string. </param>
        /// <param name="arg1">An object to write into the formatted string. </param>
        /// <param name="arg2">An object to write into the formatted string. </param>
        static public void WriteLine(Control c, string format, Object arg0, Object arg1, Object arg2)
        {
            if(L.c_me.m_default_localization == null)
            {
                //we don't localize this - there is no default
                throw new NullReferenceException("Cannot localize, no default localization set.");
            }
            c.Text += String.Format(format, L.c_me.Translate_(arg0), L.c_me.Translate_(arg1), L.c_me.Translate_(arg2)) + "\n";
        }
        /// <summary>
        /// Not actually part o fthe TextWriter class, but important for us!
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="output">The strings to write, each one that is not a NotLocalizable is output.</param>
        static public void WriteLine(Control c, params object[] output)
        {
            if(L.c_me.m_default_localization == null)
            {
                //we don't localize this - there is no default
                throw new NullReferenceException("Cannot localize, no default localization set.");
            }
            if(c.Text == null) c.Text = "";
            foreach(object s in output)
            {
                if(s.GetType() == typeof(string))
                    c.Text += L.c_me.Translate_(s);
                else
                    c.Text += L.c_me.Translate_(s);
            }
            c.Text += "\n";
        }
        #endregion

        #region Generic Object TextWriter-like implementation
        /// <summary>
        /// Writes the text representation of a Boolean value to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="value">he Boolean to write. </param>
        static public void WriteGeneric(object c, bool value)
        {
            L.c_me.WriteToGeneric(c, L.c_me.Translate(value));
        }
        /// <summary>
        /// Writes a character to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="value">The character to write to the text stream. </param>
        static public void WriteGeneric(object c, char value)
        {
            L.c_me.WriteToGeneric(c, L.c_me.Translate(value));
        }
        /// <summary>
        /// Writes a character array to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="buffer">The character array to write to the text stream. </param>
        static public void WriteGeneric(object c, char[] buffer)
        {
            L.c_me.WriteToGeneric(c, L.c_me.Translate(buffer));
        }
        /// <summary>
        /// Writes the text representation of a decimal value to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="value">The decimal value to write. </param>
        static public void WriteGeneric(object c, decimal value)
        {
            L.c_me.WriteToGeneric(c, L.c_me.Translate(value));
        }
        /// <summary>
        /// Writes the text representation of an 8-byte floating-point value to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="value">The 8-byte floating-point value to write. </param>
        static public void WriteGeneric(object c, double value)
        {
            L.c_me.WriteToGeneric(c, L.c_me.Translate(value));
        }
        /// <summary>
        /// Writes the text representation of a 4-byte signed integer to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="value">The 4-byte signed integer to write. </param>
        static public void WriteGeneric(object c, int value)
        {
            L.c_me.WriteToGeneric(c, L.c_me.Translate(value));
        }
        /// <summary>
        /// Writes the text representation of an 8-byte signed integer to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="value">The 8-byte signed integer to write. </param>
        static public void WriteGeneric(object c, long value)
        {
            L.c_me.WriteToGeneric(c, L.c_me.Translate(value));
        }
        /// <summary>
        /// Writes the text representation of an object to the text stream by calling ToString on that object.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="value">The object to write. </param>
        static public void WriteGeneric(object c, Object value)
        {
            L.c_me.WriteToGeneric(c, L.c_me.Translate(value));
        }
        /// <summary>
        /// Writes the text representation of a 4-byte floating-point value to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="value">The 4-byte floating-point value to write. </param>
        static public void WriteGeneric(object c, float value)
        {
            L.c_me.WriteToGeneric(c, L.c_me.Translate(value));
        }
        /// <summary>
        /// Writes a string to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="value">The string to write. </param>
        static public void WriteGeneric(object c, string value)
        {
            L.c_me.WriteToGeneric(c, L.c_me.Translate(value));
        }
        /// <summary>
        /// Writes the text representation of a 4-byte unsigned integer to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="value">The 4-byte unsigned integer to write. </param>
        static public void WriteGeneric(object c, uint value)
        {
            L.c_me.WriteToGeneric(c, L.c_me.Translate(value));
        }
        /// <summary>
        /// Writes the text representation of an 8-byte unsigned integer to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="value">The 8-byte unsigned integer to write. </param>
        static public void WriteGeneric(object c, ulong value)
        {
            L.c_me.WriteToGeneric(c, L.c_me.Translate(value));
        }
        /// <summary>
        /// Writes out a formatted string, using the same semantics as String.Format.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="format">The formatting string.</param>
        /// <param name="arg0">An object to write into the formatted string. (This is converted to a string)</param>
        static public void WriteGeneric(object c, string format, Object arg0)
        {
            L.c_me.WriteToGeneric(c, String.Format(format, L.c_me.Translate(arg0)));
        }
        /// <summary>
        /// Writes out a formatted string, using the same semantics as String.Format.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="format">The formatting string.</param>
        /// <param name="arg">The object array to write into the formatted string. (This is converted to a string)</param>
        static public void WriteGeneric(object c, string format, params Object[] arg)
        {
            if(L.c_me.m_default_localization == null)
            {
                //we don't localize this - there is no default
                throw new NullReferenceException("Cannot localize, no default localization set.");
            }
            object[] write = new object[arg.Length];
            for(int i = 0; i < arg.Length; i++)
                write[i] = L.c_me.Translate_(arg[i]);
            L.c_me.WriteToGeneric(c, String.Format(format, write));
        }
        /// <summary>
        /// Writes a subarray of characters to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="buffer">The character array to write data from. </param>
        /// <param name="index">Starting index in the buffer. </param>
        /// <param name="count">The number of characters to write. </param>
        static public void WriteGeneric(object c, char[] buffer, int index, int count)
        {
            char[] o = new char[count];
            for(int i = 0; i < count; i++) o[i] = buffer[index + i];
            L.c_me.WriteToGeneric(c, L.c_me.Translate(o));
        }
        /// <summary>
        /// Writes out a formatted string, using the same semantics as String.Format.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="format">The formatting string. </param>
        /// <param name="arg0">An object to write into the formatted string. </param>
        /// <param name="arg1">An object to write into the formatted string. </param>
        static public void WriteGeneric(object c, string format, Object arg0, Object arg1)
        {
            if(L.c_me.m_default_localization == null)
            {
                //we don't localize this - there is no default
                throw new NullReferenceException("Cannot localize, no default localization set.");
            }
            L.c_me.WriteToGeneric(c, String.Format(format, L.c_me.Translate_(arg0), L.c_me.Translate_(arg1)));
        }
        /// <summary>
        /// Writes out a formatted string, using the same semantics as String.Format.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="format">The formatting string. </param>
        /// <param name="arg0">An object to write into the formatted string. </param>
        /// <param name="arg1">An object to write into the formatted string. </param>
        /// <param name="arg2">An object to write into the formatted string. </param>
        static public void WriteGeneric(object c, string format, Object arg0, Object arg1, Object arg2)
        {
            if(L.c_me.m_default_localization == null)
            {
                //we don't localize this - there is no default
                throw new NullReferenceException("Cannot localize, no default localization set.");
            }
            L.c_me.WriteToGeneric(c, String.Format(format, L.c_me.Translate_(arg0), L.c_me.Translate_(arg1), L.c_me.Translate_(arg2)));
        }
        /// <summary>
        /// Not actually part o fthe TextWriter class, but important for us!
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="output">The objects to write, each one that is not a NotLocalizable is output.</param>
        static public void WriteGeneric(object c, params object[] output)
        {
            if(L.c_me.m_default_localization == null)
            {
                //we don't localize this - there is no default
                throw new NullReferenceException("Cannot localize, no default localization set.");
            }
            foreach(object s in output)
            {
                if(s.GetType() == typeof(string))
                    L.c_me.WriteToGeneric(c, L.c_me.Translate_(s));
                else
                    L.c_me.WriteToGeneric(c, L.c_me.Translate_(s));
            }
        }

        /// <summary>
        /// Writes the text representation of a Boolean value to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="value">he Boolean to write. </param>
        static public void WriteLineGeneric(object c, bool value)
        {
            L.c_me.WriteToGeneric(c, L.c_me.Translate(value) + "\n");
        }
        /// <summary>
        /// Writes a character to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="value">The character to write to the text stream. </param>
        static public void WriteLineGeneric(object c, char value)
        {
            L.c_me.WriteToGeneric(c, L.c_me.Translate(value) + "\n");
        }
        /// <summary>
        /// Writes a character array to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="buffer">The character array to write to the text stream. </param>
        static public void WriteLineGeneric(object c, char[] buffer)
        {
            L.c_me.WriteToGeneric(c, L.c_me.Translate(buffer) + "\n");
        }
        /// <summary>
        /// Writes the text representation of a decimal value to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="value">The decimal value to write. </param>
        static public void WriteLineGeneric(object c, decimal value)
        {
            L.c_me.WriteToGeneric(c, L.c_me.Translate(value) + "\n");
        }
        /// <summary>
        /// Writes the text representation of an 8-byte floating-point value to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="value">The 8-byte floating-point value to write. </param>
        static public void WriteLineGeneric(object c, double value)
        {
            L.c_me.WriteToGeneric(c, L.c_me.Translate(value) + "\n");
        }
        /// <summary>
        /// Writes the text representation of a 4-byte signed integer to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="value">The 4-byte signed integer to write. </param>
        static public void WriteLineGeneric(object c, int value)
        {
            L.c_me.WriteToGeneric(c, L.c_me.Translate(value) + "\n");
        }
        /// <summary>
        /// Writes the text representation of an 8-byte signed integer to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="value">The 8-byte signed integer to write. </param>
        static public void WriteLineGeneric(object c, long value)
        {
            L.c_me.WriteToGeneric(c, L.c_me.Translate(value) + "\n");
        }
        /// <summary>
        /// Writes the text representation of an object to the text stream by calling ToString on that object.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="value">The object to write. </param>
        static public void WriteLineGeneric(object c, Object value)
        {
            L.c_me.WriteToGeneric(c, L.c_me.Translate(value) + "\n");
        }
        /// <summary>
        /// Writes the text representation of a 4-byte floating-point value to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="value">The 4-byte floating-point value to write. </param>
        static public void WriteLineGeneric(object c, float value)
        {
            L.c_me.WriteToGeneric(c, L.c_me.Translate(value) + "\n");
        }
        /// <summary>
        /// Writes a string to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="value">The string to write. </param>
        static public void WriteLineGeneric(object c, string value)
        {
            L.c_me.WriteToGeneric(c, L.c_me.Translate(value) + "\n");
        }
        /// <summary>
        /// Writes the text representation of a 4-byte unsigned integer to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="value">The 4-byte unsigned integer to write. </param>
        static public void WriteLineGeneric(object c, uint value)
        {
            L.c_me.WriteToGeneric(c, L.c_me.Translate(value) + "\n");
        }
        /// <summary>
        /// Writes the text representation of an 8-byte unsigned integer to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="value">The 8-byte unsigned integer to write. </param>
        static public void WriteLineGeneric(object c, ulong value)
        {
            L.c_me.WriteToGeneric(c, L.c_me.Translate(value) + "\n");
        }
        /// <summary>
        /// Writes out a formatted string, using the same semantics as String.Format.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="format">The formatting string.</param>
        /// <param name="arg0">An object to write into the formatted string. (This is converted to a string)</param>
        static public void WriteLineGeneric(object c, string format, Object arg0)
        {
            L.c_me.WriteToGeneric(c, String.Format(format, L.c_me.Translate(arg0)) + "\n");
        }
        /// <summary>
        /// Writes out a formatted string, using the same semantics as String.Format.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="format">The formatting string.</param>
        /// <param name="arg">The object array to write into the formatted string. (This is converted to a string)</param>
        static public void WriteLineGeneric(object c, string format, params Object[] arg)
        {
            if(L.c_me.m_default_localization == null)
            {
                //we don't localize this - there is no default
                throw new NullReferenceException("Cannot localize, no default localization set.");
            }
            object[] write = new object[arg.Length];
            for(int i = 0; i < arg.Length; i++) write[i] = L.c_me.Translate_(arg[i]);
            L.c_me.WriteToGeneric(c, String.Format(format, write) + "\n");
        }
        /// <summary>
        /// Writes a subarray of characters to the text stream.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="buffer">The character array to write data from. </param>
        /// <param name="index">Starting index in the buffer. </param>
        /// <param name="count">The number of characters to write. </param>
        static public void WriteLine(object c, char[] buffer, int index, int count)
        {
            char[] o = new char[count];
            for(int i = 0; i < count; i++) o[i] = buffer[index + i];
            L.c_me.WriteToGeneric(c, String.Format(L.c_me.Translate(o)) + "\n");
        }
        /// <summary>
        /// Writes out a formatted string, using the same semantics as String.Format.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="format">The formatting string. </param>
        /// <param name="arg0">An object to write into the formatted string. </param>
        /// <param name="arg1">An object to write into the formatted string. </param>
        static public void WriteLineGeneric(object c, string format, Object arg0, Object arg1)
        {
            if(L.c_me.m_default_localization == null)
            {
                //we don't localize this - there is no default
                throw new NullReferenceException("Cannot localize, no default localization set.");
            }
            L.c_me.WriteToGeneric(c, String.Format(format, L.c_me.Translate_(arg0), L.c_me.Translate_(arg1)) + "\n");
        }
        /// <summary>
        /// Writes out a formatted string, using the same semantics as String.Format.
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="format">The formatting string. </param>
        /// <param name="arg0">An object to write into the formatted string. </param>
        /// <param name="arg1">An object to write into the formatted string. </param>
        /// <param name="arg2">An object to write into the formatted string. </param>
        static public void WriteLineGeneric(object c, string format, Object arg0, Object arg1, Object arg2)
        {
            if(L.c_me.m_default_localization == null)
            {
                //we don't localize this - there is no default
                throw new NullReferenceException("Cannot localize, no default localization set.");
            }
            L.c_me.WriteToGeneric(c, String.Format(String.Format(format, L.c_me.Translate_(arg0), L.c_me.Translate_(arg1), L.c_me.Translate_(arg2)) + "\n"));
        }
        /// <summary>
        /// Not actually part o fthe TextWriter class, but important for us!
        /// </summary>
        /// <param name="c">The windows control, the L.c_me.Translated replaces the Text field.</param>
        /// <param name="output">The strings to write, each one that is not a NotLocalizable is output.</param>
        static public void WriteLineGeneric(object c, params object[] output)
        {
            if(L.c_me.m_default_localization == null)
            {
                //we don't localize this - there is no default
                throw new NullReferenceException("Cannot localize, no default localization set.");
            }
            foreach(object s in output)
            {
                L.c_me.WriteToGeneric(c, L.c_me.Translate_(s));
            }
            L.c_me.WriteToGeneric(c, "\n");
        }
        #endregion

    }
}
